package com.ltmonitor.web.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import com.ltmonitor.entity.*;
import com.ltmonitor.service.*;
import com.ltmonitor.video.entity.VehicleOsd;
import com.ltmonitor.video.entity.VideoServerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.ltmonitor.util.DateUtil;
import com.ltmonitor.util.StringUtil;
import com.ltmonitor.web.util.OnlineUser;

/**
 * 用户登录时进入
 * 
 * @author admin
 * 
 */
@Controller
public class LoginAction extends GenericAction {

	// private Role role;
	//List<FunctionModel> authorizedFuncs = new ArrayList<FunctionModel>();
	@Autowired
		private ISystemConfigService systemConfigService;
		@Autowired
		private IUserPreferenceService userPreferenceService;

	/**
	 * osd字幕叠加设置
	 */
	@Autowired
	private IVehicleOsdService vehicleOsdService;
		@Autowired
		private IUserInfoService userInfoService;
		@Autowired
		private IFunctionModelService functionModelService;

		/**
		 * 验证登录用户账号，成功后跳转到主页面
		 *
		 * @param username
		 * @param password
		 * @param randomCode
		 * @return
		 */
		@RequestMapping("/login.action")
		public ModelAndView login(String username, String password,
				String randomCode) {
		/**
		 * if (!checkIp()) { saveMessage(getText("randomCode.required")); return
		 * "input"; }
		 */
		String sessRandomCode = (String) super.getFromSession("randomCode");

		if (StringUtil.isNullOrEmpty(username)) {
			return forwardWithMsg("login", "用户名不能为空");
		}
		if (password == null) {
			return forwardWithMsg("login", "密码不能为空");
		}

		try {

			SystemConfig sc = systemConfigService.getSystemConfig();
			// 是否检测验证码
			if ("yes".equals(sc.getCheckValidateCode())) {

				if (StringUtil.isNullOrEmpty(randomCode)) {
					return forwardWithMsg("login", "验证码不能为空");
				}
				if (!randomCode.equals(sessRandomCode)) {
					return forwardWithMsg("login", "验证码不正确");
				}
			}

			UserInfo user = this.userInfoService
					.getUserInfoByLoginName(username);
			if (user == null) {
				return forwardWithMsg("login", "用户名或密码错误");
			}
			String userpassword = user.getPassword();

			// String pwd = StringUtil.encodePassword(userpassword, "md5");

			if (!userpassword.equalsIgnoreCase(password)) {
				return forwardWithMsg("login", "用户名或密码错误");
			} else if (UserInfo.STATE_NORMAL.equals(user.getUserState()) == false) {
				return forwardWithMsg("login", "该账户已被停用");
			}
			loadUserDataInSession(user);
			//user.setLoginTime(new Date());
			// String hostName = getRequest().getRemoteHost();
			// user.setIp(hostName);

			/**
			 * Cookie cookie = new Cookie("w2qrs3t8ab3",
			 * StringUtil.encodePassword(user.getName(), "md5"));
			 * 
			 * String contextPath = getRequest().getContextPath();
			 * cookie.setPath((contextPath != null) && (contextPath.length() >
			 * 0) ? contextPath : "/");
			 */
			this.LogOperation("登录");

		} catch (Exception e) {
			this.log.error("", e);
			return forwardWithMsg("login", "登录时发生错误");
		}
		return new ModelAndView("redirect:/main.action");
	}

	public void loadUserDataInSession(UserInfo user) {
		if (user.getRoles().size() < 1) {
			Role role = new Role();
			role.setName("ROLE_ADMIN");
			user.getRoles().add(role);
		}
		OnlineUser onlineUser = new OnlineUser();
		onlineUser.setUserId(user.getEntityId());
		onlineUser.setMapType(user.getMapType());
		onlineUser.setName(user.getName());
		onlineUser.setSuperAdmin(user.isSuperAdmin());
		onlineUser.setCompanyId(user.getCompanyId());
		onlineUser.setLoginTime(new Date());
		// 保存在session中
		super.setOnlineUser(onlineUser);
		// 将用户分配的部门Id列表保存在session中
		this.setAuthorizedDep(user);
		this.SetUserAuthorizedFunc(user);
	}

	public void setMapInfo(UserInfo user) {
		if (user != null) {

			SystemConfig sc = systemConfigService.getSystemConfig();
			if (StringUtil.isNullOrEmpty(user.getMapType())) {
				user.setMapType(sc.getMapType());
			}

			Map<String, Object> userInfoMap = new HashMap();

			userInfoMap.put("id", user.getEntityId());
			userInfoMap.put("name", user.getName());
			if(user.getMapType() == null)
			{
				user.setMapType(sc.getMapType());
				this.getOnlineUser().setMapType(user.getMapType());
			}
			userInfoMap.put("mapType", user.getMapType());

			userInfoMap.put("mapCenterLat", user.getMapCenterLat());
			if (user.getMapCenterLat() <= 0 || user.getMapCenterLng() <= 0
					|| user.getMapLevel() <= 0) {
				// sc.setInitZoomLevel(user.getMapLevel());
				user.setMapCenterLat(sc.getInitLat());
				user.setMapCenterLng(sc.getInitLng());
				user.setMapLevel(sc.getInitZoomLevel());
			}

			userInfoMap.put("mapCenterLng", user.getMapCenterLng());
			userInfoMap.put("mapCenterLat", user.getMapCenterLat());
			userInfoMap.put("mapLevel", user.getMapLevel());
			String strLoginTime = DateUtil
					.datetimeToString(this.getOnlineUser().getLoginTime());
			userInfoMap.put("loginTime", strLoginTime);


			if (user.getRoles().size() < 1) {
				Role role = new Role();
				// role.setDescription(getText("administrator"));
				role.setName("ROLE_ADMIN");
				user.getRoles().add(role);
			}
			Role r = user.getRole();
			if (r != null)
				userInfoMap.put("roleName", r.getName());

			// JSONArray roleArray = JSONArray.fromObject(user.getRoles(),
			// this.jsonConfig);

			super.putSession(SESSION_KEY_SYSTEM_CONFIG, sc);

			UserPreference userPreference = userPreferenceService.getUserPreferenceByUserId(user.getEntityId());
			if(userPreference == null)
				userPreference = new UserPreference();
			putSession(SESSION_KEY_USER_PREFERENCE, userPreference);

			VehicleOsd vehicleOsd = this.vehicleOsdService.getVehicleOsd();
			putSession(SESSION_VEHICLE_OSD, vehicleOsd);

			// jsonObject.put("onlineUser", userInfoMap);
			putSession("onlineUserInfo", JSONObject.fromObject(userInfoMap));

			/**
			 * 转成json对象，用于页面直接获取调用
			 */
			putSession("vehicleOsdConfig", JSONObject.fromObject(vehicleOsd));


			VideoServerConfig vc = this.getVideoServerConfig();

			putSession("webIdleTime", vc.getWebIdleTime());


		} else {
		}
	}

	/**
	 * 将用户的权限信息保存在session中
	 * 
	 * @param user
	 */
	private void SetUserAuthorizedFunc(UserInfo user) {

		List<FunctionModel> authorizedFuncs = new ArrayList();
		if (user.isSuperAdmin()) {
			// 如果是超级用户，将加所有权限,可以分配所有管理部门
			authorizedFuncs = new ArrayList(this.functionModelService.loadAll());
		} else {
			Role r = user.getRole();
			if (r != null) {
				authorizedFuncs.addAll(r.getFuncs());
			}
		}
		OnlineUser onlineUser = this.getOnlineUser();
		//Map funcMap = new HashMap();
		for (FunctionModel f : authorizedFuncs) {
			if (StringUtil.isNullOrEmpty(f.getFuncName()) == false) {
				onlineUser.getFuncMap().put(f.getFuncName(), f);
			}
		}

		Collections.sort(authorizedFuncs, new SysFuncComparator());

		// 将功能权限数据以map的形式存放在session中，便于判断用户是否有某个功能的权限
		//putSession(SESSION_KEY_FUNCTION_MAP, funcMap);

		// 前端功能权限
		String webFunc = this.convertFuncsToMenu(authorizedFuncs,
				FunctionModel.FUNC_TYPE_WEB_FUNC);
		putSession(SESSION_WEB_FUNC, webFunc);

		// 根据用户分配的角色权限，得到系统顶部的主菜单，并生成菜单树在前台展现
		// 地图工具栏菜单权限
		String mapToolMenu = this.convertFuncsToMenu(authorizedFuncs,
				FunctionModel.FUNC_TYPE_MAP_TOOL);
		putSession(SESSION_MAP_TOOL_MENU, mapToolMenu);

		// 终端命令工具栏菜单权限
		String commandToolMenu = this.convertFuncsToMenu(authorizedFuncs,
				FunctionModel.FUNC_TYPE_COMMAND_TOOL);
		putSession(SESSION_COMMAND_TOOL_MENU, commandToolMenu);

		// 右键菜单权限
		String rightMenu = this.convertFuncsToMenu(authorizedFuncs,
				FunctionModel.FUNC_TYPE_RIGHT_MENU);
		putSession(SESSION_RIGHT_MENU, rightMenu);

		// 快捷菜单权限
		String mainMenu = this.convertFuncsToMenu(authorizedFuncs,
				FunctionModel.FUNC_TYPE_MAIN_MENU);
		putSession(SESSION_MAIN_MENU, mainMenu);

		// 主菜单权限
		String shortCutMenu = this.convertFuncsToMenu(authorizedFuncs,
				FunctionModel.FUNC_TYPE_MAIN_SHORT_CURT);
		putSession(SESSION_SHORT_CUT_MENU, shortCutMenu);

		// 将用户信息放在sessoin中
		setMapInfo(user);
	}

	@RequestMapping("/main.action")
	public ModelAndView main() {
		if (this.getOnlineUser() == null) {
			return forwardWithMsg("login", "用户过期，请重新登录！");
		}

		if (this.getOnlineUser().getReloadTimes() > 0) {
			// 当用户刷新页面的时候，都会进入此方法重新加载用户的所有权限进行刷新
			UserInfo user = (UserInfo) this.userInfoService.load(this
					.getOnlineUser().getEntityId());
			this.loadUserDataInSession(user);
		}
		this.getOnlineUser().setReloadTimes(1);

		ModelAndView mv =  new ModelAndView("main");
		//判断用户是否有视频相关权限
		mv.addObject("hasRealTimeVideoAuthority", hasRealTimeVideoAuthority());
		mv.addObject("hasPlayBackVideoAuthority", this.hasPlaybackVideoAuthority());
		mv.addObject("hasVideoWithAlarmAuthority", this.hasVideoWithAlarmAuthority());
		return mv;
	}

	private List<FunctionModel> findSubSyssFuncByParnetId(long id,List<FunctionModel> authorizedFuncs) {
		List<FunctionModel> subSysFuncs = new ArrayList<FunctionModel>();

		for (FunctionModel sysFunc : authorizedFuncs) {
			if (sysFunc.getParentId() == id) {
				subSysFuncs.add(sysFunc);
			}
		}
		return subSysFuncs;
	}

	/**
	 * 将用户分配的权限转换成主菜单的JSON数据，输出到前台
	 * 
	 * @param authorizedFuncs
	 *            用户分配的功能权限
	 * @param funcType
	 *            主菜单
	 * @return
	 */
	private String convertFuncsToMenu(List<FunctionModel> authorizedFuncs,
			Integer funcType) {
		String webPath = getRequest().getContextPath();

		/**
		 * 查找数据库的主菜单的顶级菜单项记录，然后将功能权限作为子菜单加入到顶级菜单中，如果顶级菜单下没有权限，将忽略不显示
		 */
		List<FunctionModel> subSysFuncs = this.functionModelService
				.queryFunctionModelList(0, funcType);
		JSONArray jsonArray = new JSONArray();
		for (FunctionModel func : subSysFuncs) {
			List<FunctionModel> childSysFuns = findChidFuncByParentId(
					func.getEntityId(), authorizedFuncs);
			JSONObject menuItem = new JSONObject();
			menuItem.put("id", "" + func.getEntityId());
			menuItem.put("text", func.getDescr());
			menuItem.put("icon", func.getIcon());
			menuItem.put("url", func.getUrl());
			menuItem.put("funcName", func.getFuncName());
			JSONObject attributes = new JSONObject();
			attributes.put("url", func.getUrl());
			menuItem.put("attributes", attributes);

			JSONArray childMenuItems = new JSONArray();
			for (FunctionModel childSysFunc : childSysFuns) {
				JSONObject childItem = new JSONObject();
				childItem.put("id", "" + childSysFunc.getEntityId());
				childItem.put("text", childSysFunc.getDescr());

				childItem.put("funcName", childSysFunc.getFuncName());
				childItem.put("icon", childSysFunc.getIcon());
				String url = childSysFunc.getUrl();
				if (!StringUtil.isNullOrEmpty(url) && url.indexOf("http://") < 0) {
					url = webPath + "/" + childSysFunc.getUrl();
				}

				childItem.put("url", url);
				attributes = new JSONObject();
				attributes.put("url", url);
				childItem.put("attributes", attributes);
				childMenuItems.add(childItem);
			}
			if (childMenuItems.size() > 0) {
				HashMap ht = new HashMap();
				// ht.put("items", childMenuItems);
				// ht.put("width", 100);
				menuItem.put("items", childMenuItems);
				jsonArray.add(menuItem); // 如果父菜单下没有子菜单，就不显示在前台
			} else if (isAuthorized(func,authorizedFuncs)) {
				jsonArray.add(menuItem);
			}

		}

		return jsonArray.toString();
	}

	private boolean isAuthorized(FunctionModel f,List<FunctionModel> authorizedFuncs) {
		for (FunctionModel fn : authorizedFuncs) {
			if (f.getEntityId() == fn.getEntityId() && fn.getDeleted() == false) {
				return true;
			}
		}
		return false;
	}

	private List<FunctionModel> findChidFuncByParentId(long parentId,
			List<FunctionModel> authorizedFuncs) {
		List subSysFuncs = new ArrayList();
		for (FunctionModel sysFunc : authorizedFuncs) {
			if (  parentId == sysFunc.getParentId()
					&& sysFunc.getDeleted() == false) {
				subSysFuncs.add(sysFunc);
			}
		}

		Collections.sort(authorizedFuncs, new SysFuncComparator());
		return subSysFuncs;
	}

	/**
	 * 退出登录
	 * 
	 * @return
	 */

	@RequestMapping("/logout.action")
	public String logout() {
		this.LogOperation("退出登录");
		try {
			this.setOnlineUser(null);
			super.clearSession();
			HttpSession session = getRequest().getSession();
			session.invalidate();// 移出所有
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
		return "login";
	}

	public String getMapToolMenu(List<FunctionModel> authorizedFuncs) {
		JSONArray jsonArray = new JSONArray();
		for (FunctionModel root : authorizedFuncs) {
			// FuncModel root = (FuncModel) iterator.next();
			if (root.getParentId() != 900200 || root.getDeleted())
				continue;

			JSONObject rootJsonObject = new JSONObject();
			rootJsonObject.put("id", "" + root.getEntityId());

			rootJsonObject.put("text", root.getDescr());
			rootJsonObject.put("icon", root.getIcon());
			rootJsonObject.put("code", root.getFuncName());
			/**
			 * if (this.selectUserFuncsMap.containsKey(root.getId()))
			 * rootJsonObject.put("checked", Boolean.valueOf(true)); else {
			 * rootJsonObject.put("checked", Boolean.valueOf(false)); }
			 */
			JSONObject attributes = new JSONObject();
			attributes.put("funcName", root.getFuncName());
			// attributes.put("style", root.getStyle());
			rootJsonObject.put("attributes", attributes);
			jsonArray.add(rootJsonObject);
		}
		return jsonArray.toString();
	}

	

	class SysFuncComparator implements Comparator<FunctionModel> {
		SysFuncComparator() {
		}

		public int compare(FunctionModel paramT1, FunctionModel paramT2) {
			int sort1 = paramT1.getMenuSort();

			int sort2 = paramT2.getMenuSort();

			return sort1 - sort2;
		}
	}

}
